package online.bukchoy.libs.tool;

import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @author cengy
 */
@Component
public class JarInstaller {

    @Value("${libs.path}")
    private String libsPath;

    @Value("${maven.path}")
    private String mvnPath;

    @PostConstruct
    public void init() {

        File libsDir = new File(libsPath);
        if (!libsDir.exists() || !libsDir.isDirectory()) {
            System.out.println("Error: libs directory does not exist or is not a directory.");
            return;
        }

        File[] jarFiles = libsDir.listFiles((dir, name) -> name.endsWith(".jar"));
        if (jarFiles == null) {
            return;
        }
        int num = 1;

        for (File jarFile : jarFiles) {
            System.err.println("=====================start install计数:" + num);
            try {
                installSingleJar(jarFile);
            } catch (Exception e) {
                System.err.println("install jar失败:" + jarFile.getName());
            }
            System.err.println("=====================done  install计数:" + num);
            ++num;
        }
    }

    private void installSingleJar(File jar) throws IOException {

        byte[] jarBytes = getFileFromJar(jar, "pom.properties");
        if (null == jarBytes) {
            System.err.println(jar.getName() + "没有pom.properties文件");
            return;
        }
        Properties properties = new Properties();
        properties.load(new ByteArrayInputStream(jarBytes));
        //pomPropertiesCache = properties;
        String infoMsg = String.format("从%s读取到pom.properties的内容:%s", jar.getName(), properties);
        System.out.println(infoMsg);
        String groupId = properties.getProperty("groupId");
        String artifactId = properties.getProperty("artifactId");
        String version = properties.getProperty("version");

        installJar(jar.getAbsolutePath(), groupId, artifactId, version);
        System.out.println(">>>install jar成功:" + jar.getName());

    }

    private void installJar(String jarPath, String groupId, String artifactId, String version) {
        String command = "cmd /c " + mvnPath + "/bin/mvn" + " install:install-file "
                + " -Dfile=" + jarPath
                + " -DgroupId=" + groupId
                + " -DartifactId=" + artifactId
                + " -Dversion=" + version
                + " -Dpackaging=jar";

        try {
            Process process = Runtime.getRuntime().exec(command);
            new StreamGobble(process.getInputStream(), "INFO").start();
            new StreamGobble(process.getErrorStream(), "ERROR").start();
            process.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
            //throw new RuntimeException(e);
        }
    }

    private static byte[] getFileFromJar(File file, String filename) {
        try (JarFile jarFile = new JarFile(file)) {
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry jarEntry = entries.nextElement();
                if (jarEntry.getName().endsWith(filename)) {
                    try (InputStream inputStream = jarFile.getInputStream(jarEntry)) {
                        byte[] bytes = new byte[inputStream.available()];
                        inputStream.read(bytes);
                        return bytes;
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String errMsg = String.format("从%s中获取%s失败", file.getName(), filename);
        System.err.println(errMsg);
        return null;
    }

    public String getLibsPath() {
        return libsPath;
    }

    public void setLibsPath(String libsPath) {
        this.libsPath = libsPath;
    }

    public String getMvnPath() {
        return mvnPath;
    }

    public void setMvnPath(String mvnPath) {
        this.mvnPath = mvnPath;
    }
}
